package com.yanqu.road.logic.cross.stronghold;

import com.yanqu.road.entity.rank.stronghold.CrossActivityUnionRank;
import com.yanqu.road.logic.bussiness.rank.CrossStrongholdActivityRankBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.RankPb;
import com.yanqu.road.pb.rank.UnionActivityRankProto;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.*;

public class CrossActivityUnionRankModel {
    private static Logger logger = LogManager.getLogger(CrossActivityUnionRankModel.class.getName());

    private int rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;
    private int defaultRankNum = 500;

    private LinkedList<CrossActivityUnionRank> rankList;

    private Comparator<CrossActivityUnionRank> sorter;

    private boolean isNeedSync = false;

    private boolean isUpdate = false;

    private int activityId;

    private int conditionType;
    private int groupId;

    private UnionActivityRankProto.UnionActivityRankListMsg.Builder rankListMsg;

    public void setRankNum(int rankNum) {
        if(rankNum < 300){
            rankNum = 300;
        }
        this.rankNum = rankNum;
        if (rankNum >= defaultRankNum) {
            defaultRankNum += rankNum;
        }
    }

    public CrossActivityUnionRankModel(int activityId,int groupId, int conditionType) {
        this.activityId = activityId;
        this.conditionType = conditionType;
        this.groupId = groupId;
        rankList = new LinkedList<>();
        rankListMsg = UnionActivityRankProto.UnionActivityRankListMsg.newBuilder();
        sorter = (o1, o2) -> {
            int result = o2.getValue().compareTo(o1.getValue());
            if (result != 0) {
                return result;
            }
            long time = o1.getLastUpdateTime() - o2.getLastUpdateTime();
            result = time > 0 ? 1 : (time == 0 ? 0 : -1);
            return result;
        };
    }

    public LinkedList<CrossActivityUnionRank> getRankList() {
        return rankList;
    }

    public UnionActivityRankProto.UnionActivityRankListMsg.Builder getRankListMsg() {
        UnionActivityRankProto.UnionActivityRankListMsg.Builder builder = UnionActivityRankProto.UnionActivityRankListMsg.newBuilder();
        for (UnionActivityRankProto.UnionActivityRankTempMsg msg : rankListMsg.getRankListList()) {
            builder.addRankList(msg);
            if (builder.getRankListCount() >= rankNum) {
                break;
            }
        }
        return builder;
    }

    public void setRankList(LinkedList<CrossActivityUnionRank> unionRankList) {
        synchronized (this) {
            rankList = new LinkedList<>(unionRankList);
            checkListValid();      //校验一下数组
            rankList.sort(sorter);
            while (rankList.size() > defaultRankNum) {
                rankList.removeLast();
            }
            initRankListMsg();
        }
    }

    /**
     * 校验数组，去掉重复数据
     */
    private void checkListValid() {
        List<Integer> needRemoveList = new ArrayList<>();
        List<String> hasUnionUidList = new ArrayList<>();
        for (int i = 0; i < rankList.size(); i++) {
            CrossActivityUnionRank unionRank = rankList.get(i);
            if (!hasUnionUidList.contains(unionRank.getUnionUid())) {
                hasUnionUidList.add(unionRank.getUnionUid());
            } else {
                needRemoveList.add(i);
            }
        }
        if (needRemoveList.size() > 0) {
            Collections.sort(needRemoveList);
            Collections.reverse(needRemoveList);
            for (int index : needRemoveList) {
                rankList.remove(index);
            }
        }
    }

    private void initRankListMsg() {
        rankListMsg = RankPb.parseCrossUnionActivityRankListMsg(rankNum, rankList);
    }

    public void removeRank(long serverId, String unionUid) {
        synchronized (this) {
            rankList.removeIf(m -> Objects.equals(m.getUnionUid(), unionUid));
            initRankListMsg();
        }
    }

    public void removeRank(String unionUid) {
        synchronized (this) {
            rankList.removeIf(m -> Objects.equals(m.getUnionUid(), unionUid));
            initRankListMsg();
            isNeedSync = true;
        }
    }

    public int getMyRank(String unionUid) {
        int rank = -1;
        synchronized (this) {
            for (int i = 0; i < rankList.size(); i++) {
                CrossActivityUnionRank unionActivityRank = rankList.get(i);
                if (Objects.equals(unionActivityRank.getUnionUid(), unionUid) ) {
                    rank = i + 1;
                    break;
                }
            }
        }
        if (rank > rankNum) {
            rank = -1;
        }
        return rank;
    }

    public BigInteger getMyUnionValue(long serverId, String unionUid) {
        synchronized (this) {
            for (CrossActivityUnionRank unionActivityRank : rankList) {
                if (Objects.equals(unionActivityRank.getUnionUid(), unionUid)) {
                    return unionActivityRank.getValue();
                }
            }
        }
        return BigInteger.ZERO;
    }

    private CrossActivityUnionRank getUnionRankInfo(String unionUid) {
        synchronized (this) {
            for (CrossActivityUnionRank unionActivityRank : rankList) {
                if (Objects.equals(unionActivityRank.getUnionUid(), unionUid)) {
                    return unionActivityRank;
                }
            }
        }
        return null;
    }

    /**
     * 更新排行
     */
    public boolean rankChange(CrossActivityUnionRank unionActivityRank) {
        if (null == unionActivityRank) {
            return false;
        }
        boolean isChange = false;
        CrossActivityUnionRank unionRank;
        synchronized (this) {
            unionRank = getUnionRankInfo(unionActivityRank.getUnionUid());
            if (null != unionRank) {
                if (0 != unionRank.getValue().compareTo(unionActivityRank.getValue())) {
                    unionRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                }
                unionRank.setValue(unionActivityRank.getValue());
                unionRank.setUnionBaseInfo(unionActivityRank.getUnionBaseInfo());
                isChange = true;
            } else {
                int size = rankList.size();
                if (size < defaultRankNum) {
                    unionActivityRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    rankList.add(unionActivityRank);
                    isChange = true;
                } else if (rankList.getLast().getValue().compareTo(unionActivityRank.getValue()) < 0) {
                    CrossActivityUnionRank rank = rankList.getLast();
                    rank.setUnionUid(unionActivityRank.getUnionUid());
                    rank.setUnionBaseInfo(unionActivityRank.getUnionBaseInfo());
                    rank.setValue(unionActivityRank.getValue());
                    rank.setServerId(unionActivityRank.getServerId());
                    rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    isChange = true;
                }
            }
            if (isChange) {
                rankList.sort(sorter);
                initRankListMsg();
                isNeedSync = true;
                isUpdate = true;
            }
        }

        return isChange;
    }

    /**
     * 更新排行,只有已经在排行中的才更新
     */
    public boolean rankChangeAlreadyInRank(String unionId, BigInteger newValue) {
        boolean isChange = false;
        CrossActivityUnionRank unionRank;
        synchronized (this) {
            unionRank = getUnionRankInfo(unionId);
            if (null != unionRank) {
                if (0 != unionRank.getValue().compareTo(newValue)) {
                    unionRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                }
                unionRank.setValue(newValue);
                isChange = true;
            }
            if (isChange) {
                rankList.sort(sorter);
                initRankListMsg();
                isNeedSync = true;
                isUpdate = true;
            }
        }

        return isChange;
    }

    /**
     * 更新排行,值已经确认修改过
     */
    public void rankEnsureChange() {
        boolean isChange = false;
        synchronized (this) {
            rankList.sort(sorter);
            initRankListMsg();
            isNeedSync = true;
            isUpdate = true;
        }
    }

    /**
     * 重置排行,值全部重置为0
     */
    public void rankValueReset() {
        synchronized (this) {
            for (CrossActivityUnionRank rankData : rankList) {
                rankData.setValue(BigInteger.ZERO);
            }
            rankList.sort(sorter);
            initRankListMsg();
            isNeedSync = false;
            isUpdate = true;
        }
    }

    /**
     * 跨服活动榜单保存
     */
    public void save() {
        LinkedList<CrossActivityUnionRank> newRankList;
        synchronized (this) {
            if (!isUpdate) {
                return;
            }
            newRankList = new LinkedList<>(rankList);
            isUpdate = false;
        }
        CrossStrongholdActivityRankBusiness.updateCrossActivityUnionRankList(activityId, groupId, conditionType, newRankList);
    }


    public boolean isNeedSync() {
        return isNeedSync;
    }

    public void setNeedSync(boolean needSync) {
        isNeedSync = needSync;
    }

    public boolean isUpdate() {
        return isUpdate;
    }

    public void setUpdate(boolean update) {
        isUpdate = update;
    }

    public int getActivityId() {
        return activityId;
    }

    public void setActivityId(int activityId) {
        this.activityId = activityId;
    }

    public int getConditionType() {
        return conditionType;
    }

    public int getGroupId() {
        return groupId;
    }
}
